package com.mj.myvirtualapp.hooktest;

import android.content.ComponentName;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;

import com.mj.myvirtualapp.R;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class EmptyActivity extends AppCompatActivity {
    public static String TAG = "EmptyActivity";
    private boolean mStartedPrinting;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

//        hookAMS();
//        try {
//            Thread.sleep(30000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
//        int i = 0;
//        while (true) {
//            i++;
//            if (i == Integer.MIN_VALUE) ;
//            i = i - 10;
//
//        }

        /**
         * 重新创建activity
         */
        //recreate();

//
//        Looper.getMainLooper().setMessageLogging(new Printer() {
//            public long mStartThreadTimeMillis;
//            public long mStartTimeMillis;
//            byte[] bytes = new byte[1024 * 1024 * 100];
//            StackTraceElement[] stackTrace;
//
//            @Override
//            public void println(String x) {
//
//                if (!mStartedPrinting) {
//                    mStartTimeMillis = System.currentTimeMillis();
//                    mStartThreadTimeMillis = SystemClock.currentThreadTimeMillis();
//                    mStartedPrinting = true;
//
//                } else {
//                    final long endTime = System.currentTimeMillis();
//                    mStartedPrinting = false;
//                    long time = endTime - mStartTimeMillis;
//                    Log.e(TAG, "println: " + time);
//                    if (time > 100) {
//                        Toast.makeText(EmptyActivity.this, "anr了  耗时：" + time, Toast.LENGTH_SHORT).show();
//                        new Thread(new Runnable() {
//                            @Override
//                            public void run() {
//                                for (StackTraceElement stackTraceElement : Looper.getMainLooper().getThread().getStackTrace()) {
//                                    Log.e(TAG, "println: " + stackTraceElement.toString());
//                                }
//
//                            }
//                        }).start();
//
////                        Map<Thread, StackTraceElement[]> allStackTraces = Thread.getAllStackTraces();
////                        for (StackTraceElement stackTraceElement : allStackTraces.get(Thread.currentThread())) {
////                            Log.e(TAG, "println1: " + stackTraceElement.toString());
////                        }
//
//
//                    }
//
//                }
//
//            }
//        });


//        for (int i = 0; i < 147; i++) {
//            new Task(i).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null);
//        }

//        mHandler.sendEmptyMessageDelayed(1,30000);
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                Log.e(TAG, "run: ");
                int temp=1;
                for (int i = 0; i < 100000; i++) {
                    Log.e(TAG, "run: " );
                }
//                try {
//                    Thread.sleep(1000);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
            }
        }, 10000);

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    //定义成static的，因为静态内部类不会持有外部类的引用
//    private final MyHandler mHandler = new MyHandler(this);
    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Log.e(TAG, "handleMessage: ");
        }
    };
    private static final Runnable sRunnable = new Runnable() {
        @Override
        public void run() {//to something}
            Log.e(TAG, "run: ");
        }
    };

    @Override
    protected void onDestroy() {
        super.onDestroy();
//        Looper.getMainLooper().setMessageLogging(null);

    }

    class Task extends AsyncTask {
        int index;

        public Task(int index) {
            this.index = index;
        }

        @Override
        protected Object doInBackground(Object[] objects) {
            try {
                Log.e(TAG, "doInBackground: " + index);
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        }
    }

    private void hookAMS() {
        try {
            Class<?> AMNClass = Class.forName("android.app.ActivityManagerNative");
            Field gDefaultField = AMNClass.getDeclaredField("gDefault");
            gDefaultField.setAccessible(true);
            Object gDefault = gDefaultField.get(null);

            Log.e(TAG, "hookAMS:gDefault " + gDefault);
            Class singleton = Class.forName("android.util.Singleton");

            Field mInstanceField = singleton.getDeclaredField("mInstance");
            mInstanceField.setAccessible(true);
            final Object rawActivityManager = mInstanceField.get(gDefault);
            Log.e(TAG, "hookAMS:rawActivityManager " + rawActivityManager);
            Class<?> iActivityManagerInterface = Class.forName("android.app.IActivityManager");
            Log.e(TAG, "hookAMS:iActivityManagerInterface " + iActivityManagerInterface);
            Object proxyInstance = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{iActivityManagerInterface}, new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    Log.e(TAG, "hookAMS:invoke " + method.getName());
                    if ("startActivity".equals(method.getName())) {
                        int index = 0;
                        for (int i = 0; i < args.length; i++) {
                            if (args[i] instanceof Intent) {
                                Log.e(TAG, "hookAMS:Intent " + args[i]);
                                index = i;
                            }
                        }

                        Intent intent = new Intent();
                        ComponentName componentName = new ComponentName("com.mj.test.hooktest", EmptyActivity.class.getName());
                        intent.setComponent(componentName);


                        args[index] = intent;
                        return method.invoke(rawActivityManager, args);
                    }

                    return method.invoke(rawActivityManager, args);
                }
            });

            mInstanceField.set(gDefault, proxyInstance);

        } catch (Exception e) {
            Log.e(TAG, "hookAMS:Exception " + e.toString());
            e.printStackTrace();
        }
    }
}
